type Weekday = Int

type Year = Int

type Month = Int

type Day = Int

-- 输入 year, 本年累积天数, 返回 周几, 0~6
week' :: Year -> Day -> Weekday
week' y d =
  let y1 = y - 1
   in (y1 + (div y1 4) - (div y1 100) + (div y1 400) + d) `mod` 7

-- 输入 year, 判断是否为闰年
isLeapYear :: Year -> Bool
isLeapYear y =
  (mod y 4 == 0) && (mod y 100 /= 0)
    || (mod y 400 == 0) && (mod y 3200 /= 0)
    || (mod y 3200 == 0) && (mod y 172800 /= 0)
    || (mod y 172800 == 0)

-- 输入 year month, 给出本月总共的 days
monthDays :: Year -> Month -> Int
monthDays y m
  | m == 2 = if not $ isLeapYear y then 28 else 29
  | elem m [1, 3, 5, 7, 8, 10, 12] = 31
  | elem m [4, 6, 9, 11] = 30
  | otherwise = error "invaid month"

-- 输入 year, month, day in month, 给出 days of year passed
accDays :: Year -> Month -> Day -> Int
accDays y m d
  | d > monthDays y m = error "invalid days"
  --   | otherwise = sum (take (m - 1) (map (monthDays y) [1 .. 12])) + d
  | otherwise = sum (map (monthDays y) [1 .. (m - 1)]) + d

-- 输入 year, month, day in month
week y m d = week' y (accDays y m d)